package com.workerhelping.service.impl;

import com.alibaba.fastjson.JSON;
import com.workerhelping.dao.ESAssistVODao;
import com.workerhelping.elasticsearchEntity.ESAssistVO;
import com.workerhelping.enums.elasticsearch.ESAssistFieldEnum;
import com.workerhelping.enums.elasticsearch.ESIncomrFieldEnum;
import com.workerhelping.enums.elasticsearch.ESIndicesEnum;
import com.workerhelping.service.ESAssistVOService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class ESAssistVOServiceImpl implements ESAssistVOService {

    @Autowired
    private ESAssistVODao esAssistVODao;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public void insertBatch(List<ESAssistVO> assistVOS) {
        esAssistVODao.saveAll(assistVOS);
    }

    /**
     *
     * 搜索所有救助信息
     * - 聚合查询
     * @param startDate 开始日期：区间搜索
     * @param endDate 结束日期：区间搜索
     * @param minPrice 最小金额：区间搜搜
     * @param maxPrice 最大金额：区间搜搜
     * @param year 资金年度：精确查询
     * @param category 资金类别：精准查询
     * @param workerId 员工id：精准查询
     * @return
     * @throws IOException
     */
    @Override
    public List<ESAssistVO> search(String startDate,
                                   String endDate,
                                   Double minPrice,
                                   Double maxPrice,
                                   String year,
                                   String category,
                                   Integer workerId) throws IOException {

        ArrayList<ESAssistVO> result = new ArrayList<>();
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 全局布尔查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (StringUtils.isEmpty(startDate) &&
                StringUtils.isEmpty(endDate) &&
                StringUtils.isEmpty(minPrice) &&
                StringUtils.isEmpty(maxPrice) &&
                StringUtils.isEmpty(year) &&
                StringUtils.isEmpty(category) &&
                StringUtils.isEmpty(workerId)) {
            boolQuery.must(QueryBuilders.matchAllQuery());
        } else {
            if (!StringUtils.isEmpty(startDate))
                boolQuery.must(QueryBuilders.rangeQuery(ESAssistFieldEnum.ASSISTDATE.getField()).gte(startDate));
            if (!StringUtils.isEmpty(endDate))
                boolQuery.must(QueryBuilders.rangeQuery(ESAssistFieldEnum.ASSISTDATE.getField()).lte(endDate));
            if (!StringUtils.isEmpty(minPrice))
                boolQuery.must(QueryBuilders.rangeQuery(ESAssistFieldEnum.MONEY.getField()).gte(minPrice));
            if (!StringUtils.isEmpty(maxPrice))
                boolQuery.must(QueryBuilders.rangeQuery(ESAssistFieldEnum.MONEY.getField()).lte(maxPrice));
            if (!StringUtils.isEmpty(year))
                boolQuery.must(QueryBuilders.termQuery(ESAssistFieldEnum.YEAR.getField(), year));
            if (!StringUtils.isEmpty(category))
                boolQuery.must(QueryBuilders.termQuery(ESAssistFieldEnum.CATEGORY.getField(), category));
            if (!StringUtils.isEmpty(workerId))
                boolQuery.must(QueryBuilders.termQuery(ESAssistFieldEnum.WORKERID.getField(), workerId));
        }

        // 公共部分 依赖布尔查询
        sourceBuilder.from(0).size(1000).sort(ESAssistFieldEnum.WORKERID.getField(), SortOrder.ASC).size(1000).
                query(boolQuery);
        searchRequest.indices(ESIndicesEnum.ASSIST.getName()).
                types(ESIndicesEnum.ASSIST.getName()).
                source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            ESAssistVO esAssistVO = JSON.parseObject(sourceAsString, ESAssistVO.class);
            result.add(esAssistVO);
        }
        return result;
    }
}
